package presentation.playgameForm_UI;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.StringTokenizer;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JToggleButton;
import javax.swing.SwingConstants;
import javax.swing.Timer;

import presentation.menuForm_UI.Picture;

import business.playgameForm_Evt.GameMode_Evt;

@SuppressWarnings("rawtypes")
public class GameMode_UI extends JFrame {

	private JPanel						panelMain			= new JPanel();
	private JPanel						panelProgress		= new JPanel();
	private JPanel						panelLevel			= new JPanel();
	private JPanel						panelTime			= new JPanel();
	private JPanel						panelButton			= new JPanel();
	private JPanel						panelButtonMain		= new JPanel();

	private int							level				= 1;

	private JLabel						lbLevel				= new JLabel("Level: " + level);
	private JLabel						lbScore				= new JLabel("Score: " + 0, JLabel.CENTER);
	private JLabel						lbHighScore			= new JLabel("High score: " + 0, JLabel.RIGHT);
	private JLabel						lbTarget			= new JLabel("");
	private JLabel						lbPoint				= new JLabel("0");
	private JLabel						lbTime				= new JLabel("Time: 2:00");
	private JLabel						lbWordShow			= new JLabel("", JLabel.CENTER);

	private JToggleButton[]				btArr				= new JToggleButton[48];
	private ArrayList<JToggleButton>	listPressedButton	= new ArrayList<JToggleButton>();
	private ArrayList<String>			listWordFound		= new ArrayList<String>();

	private int							target				= 50;
	private int							time				= 120;

	private char[]						charArr				= new char[26];

	private Timer						timer;
	private Timer						timer1;

	private JProgressBar				progressBar			= new JProgressBar(0, target);
	private MenuOption_UI				menuOption;
	private NextLevel_UI				nextLevel;

	private static final long			serialVersionUID	= 1L;

	private int							keyUp				= KeyEvent.VK_UP;
	private int							keyDown				= KeyEvent.VK_DOWN;
	private int							keyLeft				= KeyEvent.VK_LEFT;
	private int							keyRight			= KeyEvent.VK_RIGHT;
	private int							selectKey			= KeyEvent.VK_SPACE;
	private int							submitKey			= KeyEvent.VK_ENTER;
	private int							showMenuOptionKey	= KeyEvent.VK_ESCAPE;
	private int							clearKey			= KeyEvent.VK_C;

	private GameMode_Evt				event				= new GameMode_Evt(this, lbHighScore, lbScore);
	private int[]						listKey				= new int[] { keyUp, keyDown, keyLeft, keyRight, selectKey, submitKey, clearKey };
	private String[]					listSaveGame;

	public static final int				PRACTICE_MODE		= 1;
	public static final int				SINGLE_MODE			= 0;
	public static final int				SAVE_MODE			= 2;
	private int							gameMode;

	private ArrayList<String>			listLongestWord		= new ArrayList<String>();
	private ArrayList<Integer>			listTime			= new ArrayList<Integer>();

	private JToggleButton[]				listButtonBonus		= new JToggleButton[5];

	private Color[]						listColor			= new Color[11];

	private Timer[]						listTimer			= new Timer[5];

	// private boolean[] listCheck = new boolean[5];
	
	
	
	public GameMode_UI(int gameMode) {
		this.gameMode = gameMode;
		initComponents();
		event.gameMode_level = this.level;
		this.setSize(800, 600);
		this.setVisible(true);
		this.setLocationRelativeTo(null);
		this.setResizable(false);
		this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
		 this.setIconImage(Toolkit.getDefaultToolkit().getImage("src/Image/icon.png"));
	}

	private void initComponents() {
		setMainLayout();
//		this.add(panelMain);
		buttonEvent();
		keyEvent();
		windowEvent();
		pnTimeEvent();
		loadControlsKey();

		menuOption = new MenuOption_UI(this, timer, panelButton, gameMode);
		nextLevel = new NextLevel_UI(this, gameMode);
		
//		loadDefaultKey();
	}

	// ---------------------------------------------
	// Frame Properties
	// ---------------------------------------------
	
	
	private Picture pic  = new Picture();
	private JPanel pn=new JPanel(null);
	private void setMainLayout() {
		setPanelProgressLayout();
		setPanelLevelLayout();
		setPanelTimeLayout();
		setPanelButtonLayout();

		panelMain.setLayout(new GridBagLayout());

		panelButton.setBorder(BorderFactory.createEtchedBorder());
		panelLevel.setBorder(BorderFactory.createEtchedBorder());
		panelProgress.setBorder(BorderFactory.createEtchedBorder());
		panelTime.setBorder(BorderFactory.createEtchedBorder());

		JPanel panelSub = new JPanel();// panel contain panelProgress &
		// panelButton
		panelSub.setLayout(new FlowLayout(FlowLayout.LEADING, 10, 0));
		panelSub.add(panelProgress);
		panelSub.add(panelButtonMain);

		GridBagConstraints cPanelLevel = new GridBagConstraints();
		cPanelLevel.gridx = 0;
		cPanelLevel.gridy = 0;
		cPanelLevel.anchor = GridBagConstraints.NORTH;
		cPanelLevel.weighty = 1;
		cPanelLevel.insets = new Insets(8, 0, 0, 0);
		panelMain.add(panelLevel, cPanelLevel);

		GridBagConstraints cPanelSub = new GridBagConstraints();
		cPanelSub.gridx = 0;
		cPanelSub.gridy = 1;
		cPanelSub.anchor = GridBagConstraints.CENTER;
		panelMain.add(panelSub, cPanelSub);

		GridBagConstraints cPanelTime = new GridBagConstraints();
		cPanelTime.gridx = 0;
		cPanelTime.gridy = 2;
		cPanelTime.anchor = GridBagConstraints.SOUTH;
		cPanelTime.weighty = 1;
		cPanelTime.insets = new Insets(0, 0, 40, 0);
		panelMain.add(panelTime, cPanelTime);
		
		
		
		
		
		this.getContentPane().setLayout(null);
		this.add(panelMain);
		panelMain.setBounds(0, 0, 800, 600);
		panelMain.setOpaque(false);
		pn.setBounds(0, 0, 800, 600);
		pic.setBounds(0, 0, 800, 600);
		pn.setOpaque(false);
		panelSub.setOpaque(false);
		panelButton.setOpaque(false);
		
		panelButtonMain.setOpaque(false);
		panelLevel.setOpaque(false);
		panelProgress.setOpaque(false);
		panelTime.setOpaque(false);
		
		
		pic.path="src/Image/background1.png";
		pn.add(pic);
		
		this.add(pn);
		

		
	}

	private void setPanelProgressLayout() {
		panelProgress.setPreferredSize(new Dimension(128, 460));
		panelProgress.setLayout(new GridBagLayout());

		GridBagConstraints cTarget = new GridBagConstraints();
		cTarget.gridx = 0;
		cTarget.gridy = 0;
		cTarget.anchor = GridBagConstraints.NORTH;
		cTarget.insets = new Insets(0, 0, 5, 0);
		lbTarget.setText(target + "");
		panelProgress.add(lbTarget, cTarget);

		// make properties for progress bar
		progressBar.setOrientation(SwingConstants.VERTICAL);
		progressBar.setPreferredSize(new Dimension(20, 380));

		GridBagConstraints cProgressBar = new GridBagConstraints();
		cProgressBar.gridx = 0;
		cProgressBar.gridy = 1;
		cProgressBar.anchor = GridBagConstraints.CENTER;
		cProgressBar.fill = GridBagConstraints.HORIZONTAL;
		panelProgress.add(progressBar, cProgressBar);

		GridBagConstraints cPoint = new GridBagConstraints();
		cPoint.gridx = 0;
		cPoint.gridy = 2;
		cPoint.anchor = GridBagConstraints.EAST;
		cPoint.insets = new Insets(5, 0, 0, 0);
		panelProgress.add(lbPoint, cPoint);
	}

	private void setPanelLevelLayout() {
		setLabel();
		panelLevel.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0), 1, true));
		panelLevel.setPreferredSize(new Dimension(750, 30));
		panelLevel.setLayout(new GridBagLayout());

		GridBagConstraints cLevel = new GridBagConstraints();
		cLevel.gridx = 0;
		cLevel.gridy = 0;
		cLevel.anchor = GridBagConstraints.WEST;
		cLevel.insets = new Insets(0, 5, 0, 5);
		cLevel.weightx = 1;
		panelLevel.add(lbLevel, cLevel);

		GridBagConstraints cScore = new GridBagConstraints();
		cScore.gridx = 2;
		cScore.gridy = 0;
		cScore.weightx = 1;
		cScore.anchor = GridBagConstraints.CENTER;
		cScore.insets = new Insets(0, 5, 0, 5);
		panelLevel.add(lbScore, cScore);

		GridBagConstraints cHighscore = new GridBagConstraints();
		cHighscore.gridx = 4;
		cHighscore.gridy = 0;
		cHighscore.weightx = 1;
		cHighscore.insets = new Insets(0, 5, 0, 5);
		cHighscore.anchor = GridBagConstraints.EAST;
		panelLevel.add(lbHighScore, cHighscore);

	}

	private void setPanelTimeLayout() {
		panelTime.setPreferredSize(new Dimension(750, 30));
		panelTime.setLayout(new GridBagLayout());

		GridBagConstraints cTime = new GridBagConstraints();
		cTime.gridx = 0;
		cTime.gridy = 0;
		cTime.weightx = 1;
		cTime.anchor = GridBagConstraints.WEST;
		cTime.insets = new Insets(0, 5, 0, 0);
		cTime.fill = GridBagConstraints.HORIZONTAL;
		panelTime.add(lbTime, cTime);

		GridBagConstraints cWordShow = new GridBagConstraints();
		cWordShow.gridx = 1;
		cWordShow.gridy = 0;
		cWordShow.weightx = 1;
		cWordShow.anchor = GridBagConstraints.CENTER;
		cWordShow.insets = new Insets(0, 0, 0, 5);
		cWordShow.fill = GridBagConstraints.HORIZONTAL;
		cWordShow.ipadx = 300;
		panelTime.add(lbWordShow, cWordShow);

	}

	private void setLabel() {
		lbLevel.setFont(new Font("Comic Sans MS", 0, 18));
		lbScore.setFont(new Font("Comic Sans MS", 0, 18));
		lbHighScore.setFont(new Font("Comic Sans MS", 0, 18));
		lbPoint.setFont(new Font("Comic Sans MS", 0, 18));
		lbTarget.setFont(new Font("Comic Sans MS", 0, 18));
		lbTime.setFont(new Font("Comic Sans MS", 0, 18));
		lbWordShow.setFont(new Font("Comic Sans MS", 0, 18));
	}

	private void setPanelButtonLayout() {
		panelButtonMain.setPreferredSize(new Dimension(610, 460));
		panelButtonMain.setBorder(BorderFactory.createEtchedBorder());
		panelButtonMain.setLayout(null);
		panelButtonMain.add(panelButton);
		panelButton.setBounds(0, 0, 610, 460);

		panelButton.setPreferredSize(new Dimension(610, 460));
		panelButton.setBorder(BorderFactory.createEtchedBorder());
		panelButton.setLayout(new FlowLayout(FlowLayout.LEADING, 5, 5));

		setButton();

	}

	private void setButton() {

		for (int i = 0; i < charArr.length; i++) {
			charArr[i] = (char) (i + 65);
		}

		for (int i = 0; i < btArr.length; i++) {
			btArr[i] = new JToggleButton();
			btArr[i].setPreferredSize(new Dimension(70, 70));
			btArr[i].setFont(new Font("Comic Sans MS", 0, 33));
			btArr[i].setName("Normal");
			// ImageIcon("src/image/ruongvang_normal.png"));
			panelButton.add(btArr[i]);
		}

		switch (gameMode) {
			case SAVE_MODE: {
				loadSaveGame();
				event.gameMode = SAVE_MODE;
				newBoardGame(false);
			}
				break;
			case PRACTICE_MODE: {
				practiceMode();
				event.gameMode = PRACTICE_MODE;
				newBoardGame(true);
			}
				break;
			case SINGLE_MODE: {
				event.gameMode = SINGLE_MODE;
				newBoardGame(true);
			}
				break;
		}
		loadHighScore();
		refreshListBonusButton();
	}

	private void refreshListBonusButton() {
		Random rd = new Random();

		for (int i = 0; i < listButtonBonus.length; i++) {
			listButtonBonus[i] = btArr[rd.nextInt(btArr.length - 1) + 1];
		}
	}

	// ---------------------------------------------
	// End Frame Properties
	// ---------------------------------------------

	// ---------------------------------------------
	// Load Files Game
	// ---------------------------------------------
	private void loadSaveGame() {
		listSaveGame = event.loadGameSaved();

		level = Integer.parseInt(listSaveGame[0]);
		int score = Integer.parseInt(listSaveGame[1]);
		target = Integer.parseInt(listSaveGame[2]);
		int point = Integer.parseInt(listSaveGame[3]);
		time = Integer.parseInt(listSaveGame[4]);

		lbLevel.setText("Level: " + level);
		lbScore.setText("Score: " + score);
		lbTarget.setText(target + "");
		lbPoint.setText(point + "");
		event.setTime(time, lbTime);

		event.updateValueForEventUse(level, score, target, point, time);

		progressBar.setMaximum(target);
		progressBar.setValue(point);
		event.nextPoint = 2 + level/6;
	}

	private void practiceMode() {
		lbTime.setText("Time: 0:00");
		time = 0;
		lbHighScore.setText("High score: 0");
	}

	private void loadHighScore() {
		lbHighScore.setText("High score: " + event.loadHighScore());
	}

	// ---------------------------------------------
	// End Load Files Game
	// ---------------------------------------------

	// ---------------------------------------------
	// ButtonEvent & WindowEvent
	// ---------------------------------------------
	private void buttonEvent() {
		for (final JToggleButton toggleButton : btArr) {
			toggleButton.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					if(isBonus)
					{
						if(toggleButton.isSelected())
						{
							toggleButton.repaint();
							listPressedButton.add(toggleButton);
							if(showPoint(toggleButton.getName()))
							{
								new Message_UI(true, event.point, toggleButton).setVisible(true);
//								event.playSound(true);
								event.playNextLevelSound();
								setNewBonusItem();
							}
						}
						removeListBonus();
						toggleButton.setIcon(new ImageIcon(""));
					}
					else if(!isBonus)
					{
						if (toggleButton.isSelected()) {
							listPressedButton.add(toggleButton);
							toggleButton.setForeground(new Color(255, 0, 0));
							event.setTextToLabel(toggleButton, lbWordShow);
	
						}
						if (listPressedButton.size() != 0) {
							int index = 0;
							for (JToggleButton toggle : listPressedButton) {
								index++;
								if (!toggle.isSelected()) {
									String subSt = "";
									if(lbWordShow.getText().length() != 0)
										subSt = lbWordShow.getText().substring(0, index - 1);
									lbWordShow.setText(subSt);
									while (listPressedButton.size() >= index) {
										listPressedButton.get(listPressedButton.size() - 1).setSelected(false);
										listPressedButton.get(listPressedButton.size() - 1).setForeground(new Color(0, 0, 0));
										listPressedButton.remove(listPressedButton.size() - 1);
									}
									break;
								}
							}
						}
					}
				}
			});
		}
	}

	private void windowEvent() {
		this.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent evt) {
				timer1.stop();
				lbTime.setForeground(Color.black);
				timer.stop();
				panelButton.setVisible(false);
				menuOption.setVisible(true);
			}
		});
	}

	// ---------------------------------------------
	// End ButtonEvent & WindowEvent
	// ---------------------------------------------

	// ---------------------------------------------
	// KeyEvent
	// ---------------------------------------------
	private void keyEvent() {
		for (final JToggleButton toggleButton : btArr) {
			toggleButton.addKeyListener(new KeyAdapter() {

				@Override
				public void keyPressed(KeyEvent evt) {
					// -----------------------
					// Press ENTER keyboard
					// -----------------------
					enterKeyEvent(evt, toggleButton);

					// -----------------------
					// Press SPACE keyboard
					// -----------------------
					spaceKeyEvent(evt, toggleButton);

					// -------------------------
					// Get index of togglebutton
					// -------------------------
					int index = 0;
					for (int i = 0; i < btArr.length; i++) {
						if (toggleButton == btArr[i]) {
							index = i;
							break;
						}
					}

					// -----------------------
					// Press ARROWS Key
					// -----------------------
					moveEvent(evt, index);

					// -----------------------
					// Press ESCAPE Key
					// -----------------------
					escapeKeyEvent(evt);

					// -----------------------
					// Press BACKSPACE Key
					// -----------------------
					backSpaceKeyEvent(evt);
				}
			});
		}
	}

	/**
	 * This method will set focus to your button when you press arrows key to
	 * move the light to where you want to press.
	 * 
	 * @param evt
	 * @param index
	 */
	private void moveEvent(KeyEvent evt, int index) {
		// -----------------------
		// Press Up Key
		// -----------------------
		// if (evt.getKeyCode() == KeyEvent.VK_UP || evt.getKeyCode() ==
		// KeyEvent.VK_W) {
		if (evt.getKeyCode() == keyUp) {
			int indexOfNextButton = index - 8;
			if (indexOfNextButton < 0) {
				indexOfNextButton = btArr.length + indexOfNextButton;
				btArr[indexOfNextButton].requestFocus();

			}
			else {
				btArr[indexOfNextButton].requestFocus();
			}
		}

		// -----------------------
		// Press DOWN Key
		// -----------------------
		// if (evt.getKeyCode() == KeyEvent.VK_DOWN || evt.getKeyCode() ==
		// KeyEvent.VK_S) {
		if (evt.getKeyCode() == keyDown) {
			int indexOfNextButton = index + 8;
			if (indexOfNextButton > 47) {
				indexOfNextButton -= btArr.length;
				btArr[indexOfNextButton].requestFocus();

			}
			else {
				btArr[indexOfNextButton].requestFocus();
			}
		}

		// -----------------------
		// Press LEFT Key
		// -----------------------
		// if (evt.getKeyCode() == KeyEvent.VK_LEFT || evt.getKeyCode() ==
		// KeyEvent.VK_A) {
		if (evt.getKeyCode() == keyLeft) {
			int indexOfNextButton = index - 1;
			if (indexOfNextButton < 0) {
				indexOfNextButton = btArr.length + indexOfNextButton;
				btArr[indexOfNextButton].requestFocus();
			}
			else {
				btArr[indexOfNextButton].requestFocus();
			}
		}

		// -----------------------
		// Press RIGHT Key
		// -----------------------
		// if (evt.getKeyCode() == KeyEvent.VK_RIGHT || evt.getKeyCode() ==
		// KeyEvent.VK_D) {
		if (evt.getKeyCode() == keyRight) {
			int indexOfNextButton = index + 1;
			if (indexOfNextButton > 47) {
				indexOfNextButton = btArr.length - indexOfNextButton;
				btArr[indexOfNextButton].requestFocus();
			}
			else {
				btArr[indexOfNextButton].requestFocus();
			}
		}
	}

	/**
	 * This method will submit your score to your table game when you press
	 * Enter key
	 * 
	 * @param evt
	 * @param toggleButton
	 */
	private void enterKeyEvent(KeyEvent evt, JToggleButton toggleButton) {

		if (evt.getKeyCode() == submitKey) {
			if(!isBonus)
			{
				boolean wordFound = event.findWord(lbWordShow.getText());
				if (wordFound) {
					stopTimer();
					event.setPoint(lbWordShow.getText(), lbPoint, lbScore, progressBar, lbHighScore);
					listWordFound.add(lbWordShow.getText());
					listLongestWord.add(lbWordShow.getText());
					lbWordShow.setText("");
					removeList();
				}
	
				event.playSound(wordFound);
	
				Message_UI message = new Message_UI(wordFound, event.point, toggleButton);
				message.setVisible(true);
	
				if (progressBar.getValue() >= target) {
					timer.stop();
					listTime.add(120 - time);
					updateValue();
					showNextLevel();
					if (nextLevel.check) {
						nextLevelValue();
						timer.start();
						nextLevel.check = false;
					}
				}
			}
		}
	}

	/**
	 * This method will choose the letter where you pressed space bar, and also
	 * it will set your letter in button you pressed in to the word show label
	 * 
	 * @param evt
	 * @param toggleButton
	 */
	private void spaceKeyEvent(KeyEvent evt, JToggleButton toggleButton) {
		// if (evt.getKeyCode() == KeyEvent.VK_SPACE) {
		if (evt.getKeyCode() == selectKey) {
//			if(isBonus)
//			{
//				if(toggleButton.isSelected())
//				{
//					toggleButton.repaint();
//					listPressedButton.add(toggleButton);
//					
//				}
//				removeListBonus();
//				listPressedButton.add(toggleButton);
//				toggleButton.setIcon(new ImageIcon("src/image/ruongkimcuong_selected.png"));
//			}
			if(!isBonus)
			{
				if (toggleButton.isSelected()) {
					listPressedButton.add(toggleButton);
					toggleButton.setForeground(new Color(255, 0, 0));
					event.setTextToLabel(toggleButton, lbWordShow);
	
				}
				if (listPressedButton.size() != 0) {
					int index = 0;
					for (JToggleButton toggle : listPressedButton) {
						index++;
						if (!toggle.isSelected()) {
							String subSt = "";
							if(lbWordShow.getText().length() != 0)
								subSt = lbWordShow.getText().substring(0, index - 1);
							lbWordShow.setText(subSt);
							while (listPressedButton.size() >= index) {
								listPressedButton.get(listPressedButton.size() - 1).setSelected(false);
								listPressedButton.get(listPressedButton.size() - 1).setForeground(new Color(0, 0, 0));
								listPressedButton.remove(listPressedButton.size() - 1);
							}
							break;
						}
					}
				}
			}
		}
	}

	/**
	 * This method will show you some option by showing a menu by pressing
	 * Escape key
	 * 
	 * @param evt
	 */
	private void escapeKeyEvent(KeyEvent evt) {
		if (evt.getKeyCode() == showMenuOptionKey) {
			timer1.stop();
			lbTime.setForeground(Color.black);
			timer.stop();
			panelButton.setVisible(false);
			updateValueGameMode();
			menuOption.setValue(event.gameMode_level, event.gameMode_score, event.gameMode_target, event.gameMode_point, event.gameMode_time, event.gameMode_textTemp);
			menuOption.setVisible(true);
			menuOption.setLocationRelativeTo(this);
		}
	}

	/**
	 * This method will reset your chosen word and reset your list pressed
	 * button and also it will reset button color, and deSelect all your pressed
	 * button and reset your word show label
	 */
	private void backSpaceKeyEvent(KeyEvent evt) {
		// if (evt.getKeyCode() == KeyEvent.VK_BACK_SPACE || evt.getKeyCode() ==
		// KeyEvent.VK_C) {
		if (evt.getKeyCode() == clearKey || evt.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
			for (JToggleButton button : listPressedButton) {
				button.setSelected(false);
				button.setForeground(Color.black);
			}
			lbWordShow.setText("");
			while (listPressedButton.size() != 0) {
				listPressedButton.remove(listPressedButton.size() - 1);
			}
		}
	}

	// ---------------------------------------------
	// End KeyEvent
	// ---------------------------------------------

	// ---------------------------------------------
	// TimerEvent
	// ---------------------------------------------
	private void pnTimeEvent() {
		switch (gameMode) {
			case SINGLE_MODE:
			case SAVE_MODE: {
				timer = new Timer(1000, actionNormal);
			}
				break;
			case PRACTICE_MODE: {
				timer = new Timer(1000, actionPracticeMode);
			}
				break;
		}

		timer.start();

		for (int i = 0; i < listColor.length; i += 2) {
			listColor[i] = Color.red;
			if (i > 0) {
				listColor[i - 1] = Color.black;
			}
		}

		timer1 = new Timer(100, flashingColor);
		setDefaultValueCountTime();
		newTimer();
	}

	private int		counter			= 0;
	private int		counterButton1	= 0;
	private int		counterButton2	= 0;
	private int		counterButton3	= 0;
	private int		counterButton4	= 0;
	private int		counterButton5	= 0;
	private int[]	listCountTime	= new int[5];
	private Random	rd				= new Random();
	private boolean	isBonus			= false;

	private void setDefaultValueCountTime() {
		for (int i = 0; i < listCountTime.length; i++) {
			listCountTime[i] = 0;
		}
	}

	private void newTimer() {
		ActionListener[] listActionListeners = new ActionListener[] { flashingButton1, flashingButton2, flashingButton3, flashingButton4, flashingButton5 };
		for (int i = 0; i < listTimer.length; i++) {
			listTimer[i] = new Timer(100, listActionListeners[i]);
			// listTimer[i].start();
		}
	}

	private ActionListener	flashingColor		= new ActionListener() {

													@Override
													public void actionPerformed(ActionEvent e) {
														if (counter == 11) {
															counter = 0;
														}
														lbTime.setForeground(listColor[counter++]);

													}
												};

	private ActionListener	actionNormal		= new ActionListener() {

													@Override
													public void actionPerformed(ActionEvent e) {
														if(isBonus)
														{
															if(time % 5 == 0)
															{
																setBonusStageButton();
															}
														}
														if (time % 10 == 0) {
															startBonusTimer();
														}
														if (time <= 15) {
															timer1.start();
															event.clockTickingSound();
														}
														if (time == 0) {
															lbTime.setText("Time: 0:00");
															timer1.stop();
															lbTime.setForeground(Color.black);
															lbTime.setForeground(Color.black);
															timer.stop();
															endGame();
														}
														event.setTime(time--, lbTime);
													}
												};
	private ActionListener	actionPracticeMode	= new ActionListener() {

													@Override
													public void actionPerformed(ActionEvent e) {
														if (level >= 30) {
															timer.stop();
															endGame();
														}
														event.setTime(time++, lbTime);
													}
												};

	private ActionListener	flashingButton1		= new ActionListener() {

													@Override
													public void actionPerformed(ActionEvent e) {
														if (counterButton1 == 11) {
															counterButton1 = 0;
														}
														listButtonBonus[0].setForeground(listColor[counterButton1++]);
														listCountTime[0]++;
														if (listCountTime[0] == 50) {

															if (listButtonBonus[0].isSelected())
																listButtonBonus[0].setForeground(Color.red);
															else
																listButtonBonus[0].setForeground(Color.black);

															listButtonBonus[0] = btArr[rd.nextInt(btArr.length - 1) + 1];
															listTimer[0].stop();
															listCountTime[0] = 0;
														}

													}
												};
	private ActionListener	flashingButton2		= new ActionListener() {

													@Override
													public void actionPerformed(ActionEvent e) {
														if (counterButton2 == 11) {
															counterButton2 = 0;
														}
														listButtonBonus[1].setForeground(listColor[counterButton2++]);
														listCountTime[1]++;
														if (listCountTime[1] == 50) {

															if (listButtonBonus[1].isSelected())
																listButtonBonus[1].setForeground(Color.red);
															else
																listButtonBonus[1].setForeground(Color.black);

															listButtonBonus[1] = btArr[rd.nextInt(btArr.length - 1) + 1];
															listTimer[1].stop();
															listCountTime[1] = 0;
														}
													}
												};
	private ActionListener	flashingButton3		= new ActionListener() {

													@Override
													public void actionPerformed(ActionEvent e) {
														if (counterButton3 == 11) {
															counterButton3 = 0;
														}
														listButtonBonus[2].setForeground(listColor[counterButton3++]);
														listCountTime[2]++;
														if (listCountTime[2] == 50) {

															if (listButtonBonus[2].isSelected())
																listButtonBonus[2].setForeground(Color.red);
															else
																listButtonBonus[2].setForeground(Color.black);

															listButtonBonus[2] = btArr[rd.nextInt(btArr.length - 1) + 1];
															listTimer[2].stop();
															listCountTime[2] = 0;
														}
													}
												};
	private ActionListener	flashingButton4		= new ActionListener() {

													@Override
													public void actionPerformed(ActionEvent e) {
														if (counterButton4 == 11) {
															counterButton4 = 0;
														}
														listButtonBonus[3].setForeground(listColor[counterButton4++]);
														listCountTime[3]++;
														if (listCountTime[3] == 50) {

															if (listButtonBonus[3].isSelected())
																listButtonBonus[3].setForeground(Color.red);
															else
																listButtonBonus[3].setForeground(Color.black);

															listButtonBonus[3] = btArr[rd.nextInt(btArr.length - 1) + 1];

															listTimer[3].stop();
															listCountTime[3] = 0;
														}
													}
												};
	private ActionListener	flashingButton5		= new ActionListener() {

													@Override
													public void actionPerformed(ActionEvent e) {
														if (counterButton5 == 11) {
															counterButton5 = 0;
														}
														listButtonBonus[4].setForeground(listColor[counterButton5++]);
														listCountTime[4]++;
														if (listCountTime[4] == 50) {
															listButtonBonus[4].setName("Normal");

															if (listButtonBonus[4].isSelected())
																listButtonBonus[4].setForeground(Color.red);
															else
																listButtonBonus[4].setForeground(Color.black);

															listButtonBonus[4] = btArr[rd.nextInt(btArr.length - 1) + 1];
															listButtonBonus[4].setName("Bonus");
															listTimer[4].stop();
															listCountTime[4] = 0;
														}
													}
												};

	private void startBonusTimer() {
		if(!isBonus)
		{
			for (int i = 0; i < listTimer.length; i++) {
				listTimer[i].start();
			}
		}
	}

	// ---------------------------------------------
	// End TimerEvent
	// ---------------------------------------------

	// ---------------------------------------------
	// Load Controls Key
	// ---------------------------------------------
	private void loadControlsKey() {
		int[] list = event.listControlKeys();
		for (int i = 0; i < listKey.length; i++) {
			listKey[i] = list[i];
		}
	}

	// ---------------------------------------------
	// End Load Controls Key
	// ---------------------------------------------

	// ---------------------------------------------
	// Other Method
	// ---------------------------------------------
	
//	private void loadDefaultKey()
//	{
//		int keyTemp[] = event.loadKey();
//		keyUp = keyTemp[0];
//		keyDown = keyTemp[1];
//		keyLeft = keyTemp[2];
//		keyRight = keyTemp[3];
//		selectKey = keyTemp[4];
//		submitKey = keyTemp[5];
//		clearKey = keyTemp[6];
//	}
	
	/**
	 * This method will remove all item in list and also it will be change all
	 * item value and deSelected it before remove it from listButton. And then
	 * it will set random text for button deSelected
	 */
	private void removeList() {
		Random rd = new Random();
		for (final JToggleButton button : listPressedButton) {
			button.setText(charArr[rd.nextInt(26)] + "");
			button.setName("Normal");
			button.setSelected(false);
			button.setForeground(Color.black);
		}

		while (listPressedButton.size() != 0) {
			listPressedButton.remove(listPressedButton.size() - 1);
		}

	}

	private void removeListBonus()
	{
		for (final JToggleButton button : listPressedButton) {
			button.setSelected(false);
			button.setName("Normal");
			button.setForeground(Color.black);
		}

		while (listPressedButton.size() != 0) {
			listPressedButton.remove(listPressedButton.size() - 1);
		}
	}
	
	/**
	 * this method will remove all word found in list
	 */
	private void removeWordFound() {
		while (listWordFound.size() != 0) {
			listWordFound.remove(listWordFound.size() - 1);
		}
	}

	/**
	 * This will update your game status into file when you complete one level
	 */
	private void updateValue() {
		String bestWord = longestWord(listLongestWord);

		double charPerMin = charPerMin(listWordFound, listTime.get(listTime.size() - 1));
		double avgLength = avgOfLength(listLongestWord);

		int maxLength = bestWord.length();
		int totalTime = timePlay(listTime);
		int maxPoint = event.maxPointOfWord(bestWord);
		int wordFound = listWordFound.size();
		int maxLevel = level;

		if (gameMode != PRACTICE_MODE) {
			event.updateGameStatics(maxLength, bestWord, maxPoint, charPerMin, totalTime, avgLength, wordFound, maxLevel);
		}
	}

	private String longestWord(ArrayList<String> list) {
		String temp = "";

		if (list.size() > 0) {
			temp = list.get(list.size() - 1);
			for (int i = list.size() - 2; i >= 0; i--) {
				if (temp.length() < list.get(i).length()) {
					temp = list.get(i);
				}
			}
		}
		return temp;
	}

	// ListLongestWord
	private double avgOfLength(ArrayList<String> list) {
		int length = 0;
		if (list.size() != 0) {
			for (String item : list) {
				length += item.length();
			}
			return length / list.size();
		}

		return length;
	}

	private int timePlay(ArrayList<Integer> list) {
		return list.get(list.size() - 1);
	}

	private double charPerMin(ArrayList<String> list, int time) {
		double length = 0;

		for (String item : list) {
			length += item.length();
		}

		double div = length / time;

		return event.round(div * 60, 3);
	}

	/**
	 * This will get all current button text to and return it
	 * 
	 * @return text
	 */
	private String textTemp() {
		String temp = "";
		for (JToggleButton item : btArr) {
			temp += item.getText();
		}
		return temp;
	}

	/**
	 * update some value in GameMode_Evt for save event use
	 */
	private void updateValueGameMode() {
		event.gameMode_textTemp = textTemp();
		event.gameMode_target = target;
		event.gameMode_time = time;
	}

	/**
	 * This method will reset some value of game needs to be refreshed
	 */
	private void nextLevelValue() {
		if(level % 6 == 0)
		{
			bonusStage();
		}
		
		if(!isBonus)
		{
			if(level <10)
			{
				target += 20;
			}else if(level <20)
			{
				target += 40;
			}
			else if(level <30)
			{
				target += 80;
			}
			else if(level <40)
			{
				target += 100;
			}
			else if(level <60)
			{
				target += 150;
			}
			else
			{
				target += 300;
			}
			
			lbTarget.setText(target + "");
			progressBar.setMaximum(target);
			progressBar.setValue(0);
			level++;
			if(level % 6 == 0)
				event.nextPoint++;
			event.gameMode_level = level;
			event.gameMode_point = 0;
			if (gameMode == PRACTICE_MODE) {
				lbTime.setText("Time: 0:00");
				time = 0;
			}
			else {
				lbTime.setText("Time: 2:00");
				time = 120;
			}	
			
			lbLevel.setText("Level: " + level);
			lbPoint.setText("0");
			removeWordFound();
			newBoardGame(true);
		}
		else if(isBonus)
		{
			lbTime.setText("Time: 0:30");
			lbLevel.setText("Level: Bonus");
			time = 30;
		}

		
	}

	/**
	 * When your pass a level and enter to new level you must renew your game
	 * with your game mode play normal or not board. This method will renew your
	 * game board.
	 */
	private void newBoardGame(boolean playNormal) {

		char[] listTemp = (event.getAvailabelWord().toUpperCase()).toCharArray();
		if (!playNormal) {
			listTemp = listSaveGame[listSaveGame.length - 1].toCharArray();
		}
		String[] listTemp1 = new String[listTemp.length];

		for (int i = 0; i < listTemp1.length; i++) {
			listTemp1[i] = listTemp[i] + "";
		}
		List list = Arrays.asList(listTemp1);
		Collections.shuffle(list);
		for (int i = 0; i < list.size(); i++) {
			btArr[i].setText(list.get(i) + "");
		}
	}

	/**
	 * This method will show a dialog that will show you your found word, and
	 * the word that you found and your score in level you've completed
	 */
	private void showNextLevel() {
		
		event.playNextLevelSound();
		timer1.stop();
		lbTime.setForeground(Color.black);
		updateValueGameMode();
		nextLevel.setValue(event.gameMode_level, event.gameMode_score, event.gameMode_target);
		nextLevel.check = true;
		nextLevel.taListWord.setText("");
		nextLevel.lbScore.setText("Score: " + lbPoint.getText());
		if(!isBonus)
		{
			nextLevel.lbWordFound.setText("Word Found: " + listWordFound.size());
			for (String item : listWordFound) {
				nextLevel.taListWord.append(item + "\n");
			}
		}
		else if(isBonus){nextLevel.lbWordFound.setText("Word Found: 0");}
		
		nextLevel.setVisible(true);
	}

	/**
	 * This method is called when you cannot complete your game in time. It will
	 * show your score and save it into file. And back to mainMenu
	 */
	private void endGame() {
		listTime.add(120);
		updateValue();
		if(!isBonus)
		{
			if (time == 0 && progressBar.getValue() < target) {
				DialogTemp dlg = new DialogTemp(this);
				EndGame_UI end = new EndGame_UI(dlg);
				
				String longestWord = longestWord(listLongestWord);
				int maxPoint = event.maxPointOfWord(longestWord);
				end.setLabelValue(listLongestWord.size(), longestWord, maxPoint, event.gameMode_score, event.gameMode_level, formatTimeEndGame());
				end.setVisible(true);
				dlg.setVisible(true);
				
					event.showMainMenu();
			}
		}
		else if(isBonus)
		{
			if(time == 0)
			{
				showNextLevel();
				if (nextLevel.check) {
					isBonus = false;
					level++;
					resetIConBonusButton();
					nextLevelValue();
					level -- ;
					lbLevel.setText("Level: " + level);
					timer.start();
					nextLevel.check = false;
				}
			}
		}

	}
	
	private String formatTimeEndGame()
	{
		int timeTemp = 0;
		for(Integer item : listTime)
		{
			timeTemp += item;
		}
		return event.formatTimeEndGame(timeTemp);
	}
	
	private void resetIConBonusButton()
	{
		for(final JToggleButton item : btArr)
		{
			item.setName("Normal");
			item.setIcon(new ImageIcon(""));
		}
	}

	private void stopTimer() {
		Random rd = new Random();
		int counter = 0;

		for (int i = 0; i < listButtonBonus.length; i++) {
			if (listButtonBonus[i].isSelected()) {
				counter++;
				listTimer[i].stop();
				listButtonBonus[i] = btArr[rd.nextInt(btArr.length - 1) + 1];
			}
		}

		int bonus = 0;

		for (int i = 0; i < counter; i++) {
			bonus += i * rd.nextInt(50) + 30;
		}

		event.setBonusPoint(bonus);
	}

	private void bonusStage() {
		time = 0;
		isBonus = true;
		setBonusStageButton();
	}

	private JToggleButton[] listSpecialItem = new JToggleButton[9];
	
	private void setBonusStageButton() {
//		setEnabledButton(false);
		String[] listBonus = listBonusItemPath();
		for(final JToggleButton item : btArr)
		{
			item.setText("");
			item.setIcon(new ImageIcon(""));
			item.setName("Normal");
		}
		
		for(int i = 0; i<listSpecialItem.length; i++)
		{
			String path = listBonus[rd.nextInt(listBonusItemPath().length - 1) + 1];
			listSpecialItem[i] = btArr[rd.nextInt(btArr.length - 1) + 1];
			listSpecialItem[i].setIcon(new ImageIcon(path));
			listSpecialItem[i].setName(getNameItem(path));
		}
		
	}
	
	private String[] listBonusItemPath()
	{
		String[] list = new String[9];
		
		list[0] = "src/Image/Bonus_Items/apple.png";
		list[1] = "src/Image/Bonus_Items/banana.png";
		list[2] = "src/Image/Bonus_Items/cachua.png";
		list[3] = "src/Image/Bonus_Items/dautay.png";
		list[4] = "src/Image/Bonus_Items/ot.png";
		list[5] = "src/Image/Bonus_Items/duagang.png";
		list[6] = "src/Image/Bonus_Items/mango.png";
		list[7] = "src/Image/Bonus_Items/ruongkimcuong.png";
		list[8] = "src/Image/Bonus_Items/ruongvang.png";
		
		return list;
	}
	
	private String getNameItem(String item)
	{
		StringTokenizer token = new StringTokenizer(item, "/.", false);
		token.nextToken();
		token.nextToken();
		token.nextToken();
		return token.nextToken();
	}
	
	private void setNewBonusItem()
	{
		String[] listBonus = listBonusItemPath();
		for(int i = 0; i<listSpecialItem.length; i++)
		{
			if(listSpecialItem[i].isSelected())
			{
				listSpecialItem[i].setName("Normal");
				String path = listBonus[rd.nextInt(listBonusItemPath().length - 1) + 1];
				listSpecialItem[i] = btArr[rd.nextInt(btArr.length - 1) + 1];
				listSpecialItem[i].setIcon(new ImageIcon(path));
				listSpecialItem[i].setName(getNameItem(path));
			}
		}
	}

	private boolean showPoint(String buttonName)
	{
		if(buttonName.equals("apple"))
		{
			event.setPoint("WONDERFUL", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		else if(buttonName.equals("banana"))
		{
			event.setPoint("BEAUTY", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		else if(buttonName.equals("dautay"))
		{
			event.setPoint("BREAKING", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		else if(buttonName.equals("duagang"))
		{
			event.setPoint("ARMLESS", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		else if(buttonName.equals("mango"))
		{
			event.setPoint("EVERYTHING", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		else if(buttonName.equals("ot"))
		{
			event.setPoint("PLAYING", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		else if(buttonName.equals("tomato"))
		{
			event.setPoint("WONDERING", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		else if(buttonName.equals("ruongvang"))
		{
			event.setPoint("CONGRAGULATES", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		else if(buttonName.equals("ruongkimcuong"))
		{
			event.setPoint("INTERNATIONALLY", lbPoint, lbScore, progressBar, lbHighScore);
			return true;
		}
		return false;
	}
	
	// ---------------------------------------------
	// End Other Method
	// ---------------------------------------------
}